﻿using Common;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Linguist.Dictionary
{
    /// <summary>
    /// Represents a word, its spelling and its pronunciation.
    /// </summary>
    public class Word:IComparable<Word>,IWord
    {
        /// <summary>
        /// The Word representing the unknown word. 
        /// </summary>
        public static Word UNKNOWN;

        // static {
        //    Pronunciation[] pros = {Pronunciation.UNKNOWN};
        //    UNKNOWN = new Word("<unk>", pros, false);
        //    Pronunciation.UNKNOWN.setWord(UNKNOWN);
        //}

        /// <summary>
        /// the spelling of the word
        /// </summary>
        private String spelling;
        /// <summary>
        /// pronunciations of this word
        /// </summary>
        private IPronunciation[] pronunciations = {Pronunciation.UNKNOWN};  

        private Boolean _isFiller = true;

        /// <summary>
        /// Creates a Word
        /// </summary>
        /// <param name="spelling">the spelling of this word</param>
        /// <param name="pronunciations">the pronunciations of this word</param>
        /// <param name="isFiller">true if the word is a filler word</param>
        public Word(String spelling, IPronunciation[] pronunciations,
                Boolean _isFiller) 
        {
            this.spelling = spelling;
            this.pronunciations = pronunciations;
            this._isFiller = _isFiller;
        }
        /// <summary>
        /// Returns the spelling of the word.
        /// </summary>
        /// <returns></returns>
        public String getSpelling() 
        {
            return spelling;
        }
        /// <summary>
        /// Determines if this is a filler word
        /// </summary>
        /// <returns><code>true</code> if this word is a filler word, otherwise it
        ///         returns <code>false</code></returns>
        public Boolean isFiller() 
        {
            return _isFiller;
        }
        /// <summary>
        /// Returns true if this word is an end of sentence word
        /// </summary>
        /// <returns>true if the word matches Dictionary.SENTENCE_END_SPELLING</returns>
        public Boolean isSentenceEndWord() 
        {
            return this.spelling.Equals(IDictionary.SENTENCE_END_SPELLING);
        }
        /// <summary>
        /// Returns true if this word is a start of sentence word
        /// </summary>
        /// <returns>true if the word matches Dictionary.SENTENCE_START_SPELLING</returns>
        public Boolean isSentenceStartWord() 
        {
            return IDictionary.SENTENCE_START_SPELLING.Equals(this.spelling);
        }
        /// <summary>
        /// Retrieves the pronunciations of this word
        /// </summary>
        /// <param name="wordClassification">the classification of the word (typically part
        ///        of speech classification) or null if all word classifications are
        ///        acceptable. The word classification must be one of the set
        ///        returned by
        ///        <code>Dictionary.getPossibleWordClassifications</code></param>
        /// <returns>the pronunciations of this word</returns>
        public IPronunciation[] getPronunciations(IWordClassification wordClassification) 
        {
            return pronunciations;
        }

        /// <summary>
        /// Retrieves the pronunciations of this word
        /// </summary>
        /// <returns>the pronunciations of this word</returns>
        public IPronunciation[] getPronunciations() 
        {
            return pronunciations;
        }
        /// <summary>
        /// Get the highest probability pronunciation for a word
        /// </summary>
        /// <returns>the highest probability pronunciation</returns>
        public IPronunciation getMostLikelyPronunciation() 
        {
            float bestScore = float.NegativeInfinity;
            Pronunciation best = null;
            foreach (Pronunciation pronunciation in pronunciations) 
            {
                if (pronunciation.getProbability() > bestScore) 
                {
                    bestScore = pronunciation.getProbability();
                    best = pronunciation;
                }
            }
            return best;
        }

        override public int GetHashCode() 
        {
            return spelling.GetHashCode();
        }

        override public Boolean Equals(Object obj) 
        {
            return obj is Word && spelling.Equals(((Word) obj).spelling);
        }
        /// <summary>
        /// Returns a string representation of this word, which is the spelling
        /// </summary>
        /// <returns>the spelling of this word</returns>
        override  public String ToString() 
        {
            return spelling;
        }

        public int compareTo(IWord other) 
        {
            return getSpelling().CompareTo(other.getSpelling());
        }


        int IComparable<Word>.CompareTo(Word other)
        {
            return compareTo(other);
        }
    }
}
